package za.org.jcicada.comms.impl;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import za.org.jcicada.comms.IMessageListener;
import za.org.jcicada.comms.messages.CommsMessage;

/**
 * Message listener that provides a receive method for retrieving messages.
 * 
 * @author Simon Cross
 */
public class ReceiveListener implements IMessageListener {

    /** Message queue. */
    protected BlockingQueue<CommsMessage> rx = new LinkedBlockingQueue<CommsMessage>();

    /**
     * Handle a message.
     * 
     * @param message CommsMessage to process.
     */
    public void onMessage(CommsMessage message) throws InterruptedException {
        rx.put(message);
    }

    /**
     * Notify the listener that the queue it is attached to has closed.
     */
    public void onClose() {
        rx.clear();
    }

    /**
     * Retrieve a message. Block until a message is available.
     */
    public CommsMessage receive() throws InterruptedException {
        return rx.take();
    }

    /**
     * Retrieve a message. Block for timeout milliseconds before returning null
     * instead.
     * 
     * @param timeout Number of milliseconds to wait for a message.
     * @return the next CommsMessage
     */
    public CommsMessage receive(long timeout) throws InterruptedException {
        return rx.poll(timeout, TimeUnit.MILLISECONDS);
    }

    /**
     * Retrieve a message. Block for timeout time units before returning null
     * instead.
     * 
     * @param timeout Number of time units to wait for a message.
     * @param timeUnit Time units for timeout value.
     * @return the next CommsMessage
     */
    public CommsMessage receive(long timeout, TimeUnit timeUnit) throws InterruptedException {
        return rx.poll(timeout, timeUnit);
    }

}
